package com.eight.cloud.core.global.model;

import cn.hutool.core.util.ObjectUtil;
import com.eight.cloud.core.global.constant.DataScopeConstants;
import com.eight.cloud.core.global.constant.UserTypeEnum;
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 上下文认证信息
 *
 * @ClassName: SecuritySession
 * @Author: TXC
 * @Date: 2025-02-20 16:19
 **/
@Data
public class BaseUser {
    /**
     * 用户id
     */
    private String uuid;
    /**
     * 租户id
     */
    private String tenantId;

    /**
     * 部门id
     */
    private String deptId;

    /**
     * 用户类型
     */
    private UserTypeEnum userType;

    /**
     * 角色列表
     */
    private List<SysRole> roles = new ArrayList<>();

    /**
     * 权限列表<权限编码，权限信息>
     */
    private Map<String, UserPermission> permissions = new HashMap<>();

    /**
     * 获取权限编码列表
     * @return 权限编码列表
     */
    public List<String> obtainPermissionsCodeList() {
        Set<String> permissionSet = new HashSet<>();
        permissions.forEach((key, value) -> {
            if (value.isHasPermission()) {
                permissionSet.add(value.getCode());
            }
        });
        return new ArrayList<>(permissionSet);
    }

    /**
     * 获取权限列表 值为false表示不拥有权限，值为true表示用于权限
     * @return 权限列表
     */
    public Map<String, Boolean> obtainPermissionsMap() {
        Map<String, Boolean> permissionMap = new HashMap<>();
        permissions.forEach((key, value) -> {
            permissionMap.put(value.getCode(), value.isHasPermission());
        });
        return permissionMap;
    }


    /**
     * 通过角色权限码获取角色列表
     * @param permissionsCode 权限码
     * @return 角色列表
     */
    public List<SysRole> obtainRolesByPermissionsCode(String permissionsCode) {
        List<SysRole> matchedRoles = new ArrayList<>();
        // 遍历所有角色
        for (SysRole role : roles) {
            // 检查permissions是否为null
            if (ObjectUtil.isNotNull(role.getPermissions())) {
                Map<String, SysPermission> permissionMap = role.getPermissions().stream().collect(Collectors.toMap(SysPermission::getCode, e -> e));
                if (permissionMap.containsKey(permissionsCode)) {
                    matchedRoles.add(role);
                }
            }
        }
        return matchedRoles;
    }

    /**
     * 获取角色列表最高数据权限
     * @param roles 角色列表
     * @return 数据权限模型
     */
    public DataScopeModel obtainRoleDataScope(List<SysRole> roles) {
        Map<String, List<SysRole>> roleMap = roles.stream().collect(Collectors.groupingBy(SysRole::getDataScope,
                Collectors.toList()));
        if (roleMap.containsKey(DataScopeConstants.DATA_SCOPE_ALL)) {
            return new DataScopeModel(DataScopeConstants.DATA_SCOPE_ALL, Collections.emptyList());
        } else if (roleMap.containsKey(DataScopeConstants.DATA_SCOPE_CUSTOM) || roleMap.containsKey(DataScopeConstants.DATA_SCOPE_DEPT) || roleMap.containsKey(DataScopeConstants.DATA_SCOPE_DEPT_AND_CHILD)) {
            List<SysRole> roleList = new ArrayList<>();
            roleList.addAll(roleMap.getOrDefault(DataScopeConstants.DATA_SCOPE_CUSTOM, new ArrayList<>()));
            roleList.addAll(roleMap.getOrDefault(DataScopeConstants.DATA_SCOPE_DEPT, new ArrayList<>()));
            roleList.addAll(roleMap.getOrDefault(DataScopeConstants.DATA_SCOPE_DEPT_AND_CHILD, new ArrayList<>()));
            Set<String> deptIdList = new HashSet<>();
            roleList.forEach(role -> {
                if (ObjectUtil.isNotNull(role.getDeptIds())) {
                    deptIdList.addAll(role.getDeptIds());
                }
            });
            return new DataScopeModel(DataScopeConstants.DATA_SCOPE_DEPT, new ArrayList<>(deptIdList));
        } else {
            if (ObjectUtil.isNotEmpty(roles)) {
                return new DataScopeModel(DataScopeConstants.DATA_SCOPE_SELF, Collections.emptyList());
            }
            return null;
        }
    }

    /**
     * 获取赋予权限最高数据权限的角色
     * @param permissionsCode 权限码
     * @return 数据权限模型
     */
    public DataScopeModel obtainRoleDataScope(String permissionsCode) {
        List<SysRole> roles = obtainRolesByPermissionsCode(permissionsCode);
        DataScopeModel dataScopeModel = obtainRoleDataScope(roles);
        UserPermission permission = permissions.get(permissionsCode);
        // 如果权限单独设置了权限范围，则覆盖角色的权限范围
        if (ObjectUtil.isNotEmpty(permission.getDataScope())) {
            dataScopeModel.setDataScope(permission.getDataScope());
        }
        if (ObjectUtil.isNotEmpty(permission.getDeptIds())) {
            dataScopeModel.setDeptIds(permission.getDeptIds());
        }
        return dataScopeModel;
    }
}
